package com.boglond.builder;

import com.boglond.entity.ColumnInfoDO;
import com.boglond.entity.TableInfoDO;
import com.boglond.util.PropertyUtil;
import com.boglond.util.XmlUtil;
import org.dom4j.Document;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

public class GenerateXMLInterfaceImpl implements GenerateXMLInterface {

    private static final Logger log = LoggerFactory.getLogger(GenerateXMLInterfaceImpl.class);

    private static String PO_CLASS_PACKAGE_PATH = PropertyUtil.getValueByKey("po.class.package.path");

    private static String DAO_CLASS_PACKAGE_PATH = PropertyUtil.getValueByKey("dao.class.package.path");

    @Override
    public void createMapperXML(List<TableInfoDO> tableInfoDOList) {

        log.info(">> 表信息如下:{}",tableInfoDOList);
        for(TableInfoDO tableInfo: tableInfoDOList){
            XmlUtil.createBasicTableXmlMapperFile(tableInfo.getEntityName() + "Mapper",
                    DAO_CLASS_PACKAGE_PATH + "." + tableInfo.getEntityName() + "Mapper");
            Document document = XmlUtil.xmlConvertDocument(tableInfo.getEntityName() + "Mapper");
            Element root = document.getRootElement();

            //生成BaseResultMap
            Element resultMap = root.addElement("resultMap");
            resultMap.addAttribute("id", "BaseResultMap");
            resultMap.addAttribute("type", PO_CLASS_PACKAGE_PATH + "."+
                    tableInfo.getEntityName() + "PO");
            List<ColumnInfoDO> columnsInfo = tableInfo.getColumnsInfo();
            Element result = null;
            for(ColumnInfoDO column: columnsInfo){
                result = resultMap.addElement("result");
                result.addAttribute("column", column.getColumnName());
                result.addAttribute("jdbcType", column.getDataTypeName());
                result.addAttribute("property", column.getHumpColumnName());
            }

            //生成Base_Column_List
            Element sql = root.addElement("sql");
            sql.addAttribute("id", "Base_Column_List");
            sql.setText(tableInfo.getColumnsStr());

            //生成selectById
            Element selectById = root.addElement("select");
            selectById.addAttribute("id", "selectById");
            selectById.addAttribute("parameterType", "java.lang.Long");
            selectById.addAttribute("resultMap", "BaseResultMap");

            selectById.addText("select ");

            Element selectByIdInclude = selectById.addElement("include");
            selectByIdInclude.addAttribute("refid", "Base_Column_List");
            selectById.addText(" from " + tableInfo.getTableName() );
            selectById.addText(" where ");
            selectById.addText(new StringBuffer().
                    append(tableInfo.getPrimaryKeyColumn())
                    .append(" = ")
                    .append("#{")
                    .append(tableInfo.getPrimaryKeyName())
                    .append(",jdbcType=")
                    .append(tableInfo.getPrimaryKeyType())
                    .append("}")
                    .append(" and del_flag = 0").toString())
            ;

            //生成deleteByIdPhysics
//            Element deleteByIdPhysics = root.addElement("delete");
//            deleteByIdPhysics.addAttribute("id", "deleteByIdPhysics");
//            deleteByIdPhysics.addAttribute("parameterType", "java.lang.Long");
//            deleteByIdPhysics.addText("delete from "+ tableInfo.getTableName());
//            deleteByIdPhysics.addText(" where ");
//            deleteByIdPhysics.addText(new StringBuffer().
//                    append(tableInfo.getPrimaryKeyColumn())
//                    .append(" = ")
//                    .append("#{")
//                    .append(tableInfo.getPrimaryKeyName())
//                    .append(",jdbcType=")
//                    .append(tableInfo.getPrimaryKeyType())
//                    .append("}").toString());

            //生成deleteBatchByIdsPhysics
//            Element deleteBatchByIdsPhysics = root.addElement("delete");
//            deleteBatchByIdsPhysics.addAttribute("id", "deleteBatchByIdsPhysics");
//            deleteBatchByIdsPhysics.addAttribute("parameterType", "java.util.List");
//            deleteBatchByIdsPhysics.addText("delete from "+ tableInfo.getTableName());
//            deleteBatchByIdsPhysics.addText(" where ");
//            deleteBatchByIdsPhysics.addText(new StringBuffer().
//                    append(tableInfo.getPrimaryKeyColumn())
//                    .append(" in ( ").toString());

//            Element deleteBatchByIdsPhysicsForeach = deleteBatchByIdsPhysics.addElement("foreach");
//            deleteBatchByIdsPhysicsForeach.addAttribute("item", "item");
//            deleteBatchByIdsPhysicsForeach.addAttribute("collection", "list");
//            deleteBatchByIdsPhysicsForeach.addAttribute("separator", ",");
//            deleteBatchByIdsPhysicsForeach.addText(new StringBuffer()
//                    .append("#{")
//                    .append(tableInfo.getPrimaryKeyName())
//                    .append(",jdbcType=")
//                    .append(tableInfo.getPrimaryKeyType())
//                    .append("}").toString());
//
//            deleteBatchByIdsPhysics.addText(" ) ");

            //生成deleteBatchByIdsLogic
//            Element deleteBatchByIdsLogic = root.addElement("delete");
//            deleteBatchByIdsLogic.addAttribute("id", "deleteBatchByIdsLogic");
//            deleteBatchByIdsLogic.addAttribute("parameterType", "java.util.Map");
//            deleteBatchByIdsLogic.addText(" update "+ tableInfo.getTableName());
//            deleteBatchByIdsLogic.addText(new StringBuffer().append(" set del_flag = 1,").
//                    append(" updater = #{updater,jdbcType=VARCHAR},").
//                    append(" update_time = #{updateTime,jdbcType=TIMESTAMP} ").
//                    append(" where del_flag = 0").
//                    append(" and ").toString());
//
//            deleteBatchByIdsLogic.addText(new StringBuffer().
//                    append(tableInfo.getPrimaryKeyColumn())
//                    .append(" in ( ").toString());
//
//            Element deleteBatchByIdsLogicForeach = deleteBatchByIdsLogic.addElement("foreach");
//            deleteBatchByIdsLogicForeach.addAttribute("item", "item");
//            deleteBatchByIdsLogicForeach.addAttribute("collection", "list");
//            deleteBatchByIdsLogicForeach.addAttribute("separator", ",");
//            deleteBatchByIdsLogicForeach.addText(new StringBuffer()
//                    .append("#{")
//                    .append(tableInfo.getPrimaryKeyName())
//                    .append(",jdbcType=")
//                    .append(tableInfo.getPrimaryKeyType())
//                    .append("}").toString());
//
//            deleteBatchByIdsLogic.addText(" ) ");

            //生成insertBatch
            Element insertBatch = root.addElement("insert");
            insertBatch.addAttribute("id", "insertBatch");
            insertBatch.addText(" insert into "+ tableInfo.getTableName() + " (");
            Element insertBatchInclude = insertBatch.addElement("include");
            insertBatchInclude.addAttribute("refid", "Base_Column_List");
            insertBatch.addText(" ) values ");
            Element insertBatchForeach = insertBatch.addElement("foreach");
            insertBatchForeach.addAttribute("item", "item");
            insertBatchForeach.addAttribute("collection", "list");
            insertBatchForeach.addAttribute("separator", ",");

            insertBatchForeach.addText(" ( ");
            int size = columnsInfo.size();
            ColumnInfoDO column = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                if(i == (size - 1)){
                    insertBatchForeach.addText(new StringBuffer()
                            .append("#{")
                            .append("item.")
                            .append(column.getHumpColumnName())
                            .append("}").toString());
                }else{
                    insertBatchForeach.addText(new StringBuffer()
                            .append("#{")
                            .append("item.")
                            .append(column.getHumpColumnName())
                            .append("},").toString());
                }
            }
            insertBatchForeach.addText(" ) ");

            //生成insertSelective
            Element insertSelective = root.addElement("insert");
            insertSelective.addAttribute("id", "insert");
            insertSelective.addAttribute("parameterType", PO_CLASS_PACKAGE_PATH + "."+ tableInfo.getEntityName()+"PO");
            insertSelective.addText(" insert into "+ tableInfo.getTableName());

            Element insertSelectiveTrim = insertSelective.addElement("trim");
            insertSelectiveTrim.addAttribute("prefix", "(");
            insertSelectiveTrim.addAttribute("suffix", ")");
            insertSelectiveTrim.addAttribute("suffixOverrides", ",");
            Element insertSelectiveTrimIf = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                insertSelectiveTrimIf = insertSelectiveTrim.addElement("if");
                if(column.getDataType() == 12){
                    insertSelectiveTrimIf.addAttribute("test", column.getHumpColumnName()
                            + " != null and " + column.getHumpColumnName() + " !=''");
                    insertSelectiveTrimIf.addText(column.getColumnName() +",");
                }else{
                    insertSelectiveTrimIf.addAttribute("test", column.getHumpColumnName() + " != null");
                    insertSelectiveTrimIf.addText(column.getColumnName() +",");
                }
            }
            Element insertSelectiveTrim2 = insertSelective.addElement("trim");
            insertSelectiveTrim2.addAttribute("prefix", "value (");
            insertSelectiveTrim2.addAttribute("suffix", ")");
            insertSelectiveTrim2.addAttribute("suffixOverrides", ",");
            Element insertSelectiveTrim2If = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                insertSelectiveTrim2If = insertSelectiveTrim2.addElement("if");

                if(column.getDataType() == 12){
                    insertSelectiveTrim2If.addAttribute("test", column.getHumpColumnName()
                            + " != null and " + column.getHumpColumnName() + " !=''");
                }else{
                    insertSelectiveTrim2If.addAttribute("test", column.getHumpColumnName() + " != null");
                }
                insertSelectiveTrim2If.addText(new StringBuffer()
                        .append("#{")
                        .append(column.getHumpColumnName())
                        .append(",jdbcType=")
                        .append(column.getDataTypeName())
                        .append("}")
                        .append(",").toString());

            }

            //生成updateBySelective
            Element updateBySelective = root.addElement("update");
            updateBySelective.addAttribute("id", "update");
            updateBySelective.addAttribute("parameterType", PO_CLASS_PACKAGE_PATH +
                    "."+ tableInfo.getEntityName()+"PO");
            updateBySelective.addText(" update "+ tableInfo.getTableName());
            Element updateBySelectiveSet = updateBySelective.addElement("set");
            Element updateBySelectiveSetIf = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                updateBySelectiveSetIf = updateBySelectiveSet.addElement("if");
                if(column.getDataType() == 12){
                    updateBySelectiveSetIf.addAttribute("test", column.getHumpColumnName()
                            + " != null and " + column.getHumpColumnName() + " !=''");
                }else{
                    updateBySelectiveSetIf.addAttribute("test", column.getHumpColumnName() + " != null");
                }
                updateBySelectiveSetIf.addText(column.getColumnName() +"=");
                updateBySelectiveSetIf.addText(new StringBuffer()
                        .append("#{")
                        .append(column.getHumpColumnName())
                        .append(",jdbcType=")
                        .append(column.getDataTypeName())
                        .append("}")
                        .append(",").toString());

            }
            updateBySelective.addText(" where ");
            updateBySelective.addText(new StringBuffer().
                    append(tableInfo.getPrimaryKeyColumn())
                    .append(" = ")
                    .append("#{")
                    .append(tableInfo.getPrimaryKeyName())
                    .append(",jdbcType=")
                    .append(tableInfo.getPrimaryKeyType())
                    .append("}").toString());

            //生成selectByConditionPage
            Element selectByConditionPage = root.addElement("select");
            selectByConditionPage.addAttribute("id", "select");
            selectByConditionPage.addAttribute("parameterType", PO_CLASS_PACKAGE_PATH + "."+
                    tableInfo.getEntityName()+"PO");
            selectByConditionPage.addAttribute("resultMap", "BaseResultMap");

            selectByConditionPage.addText("select ");

            Element selectByConditionPageInclude = selectByConditionPage.addElement("include");
            selectByConditionPageInclude.addAttribute("refid", "Base_Column_List");
            selectByConditionPage.addText(" from " + tableInfo.getTableName() );
            Element selectByConditionPageWhere = selectByConditionPage.addElement("where");
            Element selectByConditionPageWhereIf = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                selectByConditionPageWhereIf = selectByConditionPageWhere.addElement("if");

                if(column.getDataType() == 12){
                    selectByConditionPageWhereIf.addAttribute("test", column.getHumpColumnName() + " != null and "
                            + column.getHumpColumnName() + " != ''");
                }else{
                    selectByConditionPageWhereIf.addAttribute("test", column.getHumpColumnName() + " != null");
                }
                selectByConditionPageWhereIf.addText(" and " + column.getColumnName() +"=");
                selectByConditionPageWhereIf.addText(new StringBuffer()
                        .append("#{")
                        .append(column.getHumpColumnName())
                        .append(",jdbcType=")
                        .append(column.getDataTypeName())
                        .append("}")
                        .toString());

            }
            selectByConditionPage.addText(" ORDER BY update_time DESC ");

            Element selectByConditionPageLimit = selectByConditionPage.addElement("if");
            selectByConditionPageLimit.addAttribute("test", " offset != null and pageSize != null");
            selectByConditionPageLimit.addText(" LIMIT #{offset}, #{pageSize} ");

            //生成countByConditionPage
            Element countByConditionPage = root.addElement("select");
            countByConditionPage.addAttribute("id", "count");
            countByConditionPage.addAttribute("parameterType", PO_CLASS_PACKAGE_PATH + "."+
                    tableInfo.getEntityName()+"PO");
            countByConditionPage.addAttribute("resultType", "java.lang.Long");

            countByConditionPage.addText("select count(1) ");

            countByConditionPage.addText(" from " + tableInfo.getTableName() );
            Element countByConditionPageWhere = countByConditionPage.addElement("where");
            Element countByConditionPageWhereIf = null;
            for(int i = 0; i < size; i++){
                column = columnsInfo.get(i);
                countByConditionPageWhereIf = countByConditionPageWhere.addElement("if");
                if(column.getDataType() == 12){
                    countByConditionPageWhereIf.addAttribute("test", column.getHumpColumnName() + " != null and "
                            + column.getHumpColumnName() + " != ''");
                }else{
                    countByConditionPageWhereIf.addAttribute("test", column.getHumpColumnName() + " != null");
                }
                countByConditionPageWhereIf.addText(" and " + column.getColumnName() +"=");
                countByConditionPageWhereIf.addText(new StringBuffer()
                        .append("#{")
                        .append(column.getHumpColumnName())
                        .append(",jdbcType=")
                        .append(column.getDataTypeName())
                        .append("}")
                        .toString());

            }

            //生成deleteByConditionLogic
            Element deleteByConditionLogic = root.addElement("update");
            deleteByConditionLogic.addAttribute("id", "delete");
            deleteByConditionLogic.addAttribute("parameterType", PO_CLASS_PACKAGE_PATH + "."+
                    tableInfo.getEntityName()+"PO");

            deleteByConditionLogic.addText("update " + tableInfo.getTableName());

            deleteByConditionLogic.addText(" " +
                    "set del_flag = 1," +
                    "update_time = #{updateTime,jdbcType=TIMESTAMP}," +
                    "updater = #{updater,jdbcType=VARCHAR}" );
            Element deleteByConditionLogicWhere = deleteByConditionLogic.addElement("where");

            deleteByConditionLogicWhere.addText(new StringBuffer().
                    append(tableInfo.getPrimaryKeyColumn())
                    .append(" = ")
                    .append("#{")
                    .append(tableInfo.getPrimaryKeyName())
                    .append(",jdbcType=")
                    .append(tableInfo.getPrimaryKeyType())
                    .append("}").toString());

            XmlUtil.documentConvertXml(document,tableInfo.getEntityName() + "Mapper");

        }

    }

}
